package fishBids.group3.behaviour.auctioneer;

import es.upm.agents.ontology.ListProduct;
import es.upm.agents.ontology.ToRegister;
import fishBids.group3.AgAuctioneer;
import fishBids.group3.common.Constants;
import fishBids.group3.communicationobjects.ToCreateAccount;
import fishBids.group3.utils.Utils;
import jade.content.lang.Codec;
import jade.content.lang.Codec.CodecException;
import jade.content.onto.Ontology;
import jade.content.onto.OntologyException;
import jade.content.onto.basic.Action;
import jade.core.AID;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

import java.util.Date;

public class AuctioneerRegisterBehaviour extends CyclicBehaviour {


	/**
	 * 
	 */
	private static final long serialVersionUID = -7849898268481341356L;

	public AuctioneerRegisterBehaviour(AgAuctioneer auctioneer, Codec codec, Ontology ontolgy, ListProduct listProduct){
		this.auctioneerAgent = auctioneer;
		this.codec = codec;
		this.ontology = ontolgy;
		this.listProduct = listProduct;
	}

	@Override
	public void action()

	{
		// Waits for estimation requests
		// Receive the message 
		MessageTemplate mt = MessageTemplate.and(
				MessageTemplate.MatchProtocol(Constants.REGISTER), MessageTemplate.and( 
					    MessageTemplate.MatchLanguage(codec.getName()), 
					    MessageTemplate.MatchOntology(ontology.getName()) ));
		
		ACLMessage msg = auctioneerAgent.receive(mt); 
		//System.out.println("Auctioneer >>>Register waiting for a message");
		if (msg != null)

		{
			if (msg.getPerformative() != ACLMessage.REQUEST) {
				ACLMessage reply = msg.createReply();
				reply.setLanguage(codec.getName());
				reply.setOntology(ontology.getName());
				reply.setPerformative(ACLMessage.NOT_UNDERSTOOD);
				//System.out.println("Auctioneer>>> Sending Register NOT_UNDERSTOOD message");
				auctioneerAgent.send(reply);
				return;
			}
			//System.out.println("Auctioneer >>> I received a request from: " + msg.getSender().getLocalName() );
				
			if ( isRegisterRefused(msg.getSender()) )
			{
				ACLMessage reply = msg.createReply();
				reply.setLanguage(codec.getName());
				reply.setOntology(ontology.getName());
				reply.setPerformative(ACLMessage.REFUSE);
				reply.setProtocol(Constants.REGISTER);
				//System.out.println("Auctioneer >>>> Registration refused");
				auctioneerAgent.send(reply);
				return;
			}

//			Storing of the bidder
			this.auctioneerAgent.addBidderToBiddersRegistered(msg.getSender());
			
			ACLMessage reply = msg.createReply();
			reply.setLanguage(codec.getName());
			reply.setOntology(ontology.getName());
			reply.setPerformative(ACLMessage.INFORM);
			reply.setProtocol(Constants.REGISTER);
			
			ToRegister toRegister = new ToRegister();
			toRegister.setProductList(listProduct);
			Action agAction = new Action(msg.getSender(),toRegister);
			
			try {
				auctioneerAgent.getContentManager().fillContent(reply, agAction);
				System.out.println("auctioneer3: registered "  + msg.getSender().getName() + " for the auction");
				auctioneerAgent.send(reply);
			} catch (CodecException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (OntologyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}else {
			if(! this.auctioneerAgent.isRegistrationOver()){
				if((new Date()).getTime() - startingRegisterTime.getTime() >= timeout){
					this.auctioneerAgent.setRegistrationOver(true);	
				}else{
					this.block(10000);
				}
			}else{
				this.block();
			}
			
		}



	}
	
	private boolean isRegisterRefused(AID aid) {
		
		if((new Date()).getTime() - startingRegisterTime.getTime() >= 30000)
			return true;
		
		ToCreateAccount toCreateAccount = new ToCreateAccount();
		toCreateAccount.setAgentID(aid);
		
		//System.out.println("Auctioneer >>>> ready to create an account in the bank!!!");
		
		Utils.sendGenericMessageWithObject(ACLMessage.REQUEST, auctioneerAgent.getBankID(),
				Constants.CREATE_ACCOUNT, auctioneerAgent, toCreateAccount);
		
		//System.out.println("Auctioneer >>>> se envio el mensaje");
		
		MessageTemplate mt = MessageTemplate.and(
				MessageTemplate.MatchProtocol(Constants.CREATE_ACCOUNT), MessageTemplate.and( 
					    MessageTemplate.MatchLanguage(codec.getName()), 
					    MessageTemplate.MatchOntology(ontology.getName()) ));
		
		ACLMessage msg = auctioneerAgent.blockingReceive(mt); 
		
		//System.out.println("Auctioneer>>>> se recibio el mensaje");
		
		if(msg.getPerformative() == ACLMessage.FAILURE ){
			return true;
		}
		
		//System.out.println("Auctioneer >>>> received an inform from the bank!!!");
		return false;
	}

	
	AgAuctioneer auctioneerAgent;
	ListProduct listProduct;
	Ontology ontology;
	Codec codec;
	final Date startingRegisterTime = new Date();
	int timeout = Integer.parseInt(Utils.getProperty(Constants.REGISTERING_TIME));


}
